Data Tutorial 5: List Processing

 

Introduction:

The zl object is used for different types of list processing functions. The vexpr object is used for processing lists through a mathematic equation. Finally, the prob object is used to create a table of probabilities for music creation.

 

Running the sequencing patch:

The basic function of the step sequencer should be familiar: the metro drives a 32 position counter, whose output is turned into a fetch message for the three multislider objects. The output of the multisliders are sent to two different makenote/ noteoutcombinations; the two drum multisliders are sent to a noteout object assigned to MIDI channel 10, while the melody is sent to a noteout object assigned to MIDI channel 1.

The two drum channels feature a simplified way of selecting drums – their multisliderobjects are limited to only three values each. The select objects used with these objects are a way of remapping the multislider contents (0, 1 or 2) to an instrument (none, kick/closed hi-hat and snare/open hi-hat, respectively). In this way, the full range of the multislider has significance, and the output value is easy to work with.

 

Working with prob (probabilities)

The setup of the probability table is done through the large message triggered when the patcher opened by the loadbang. The way that our probability table works is based on transitions - these are defined by three element lists containing current value, another value and a weighting value used to determine how likely a transition is from current value to another value. So, for example, 0 1 2 means that the weighting applied to a transition from 0 to 1 is 2. What does 2 mean? It doesn’t really mean anything specific – it only has a defined value in relation to all of the other weights for that transition.

The message box used for the hi-hat probability tables sets up all of the possible transitions within a single three value (0, 1,2) set. Since you can only be at one location at a time, the probabilities are dependent on the current value. Let’s look at probability calculations if the current step is 0:
Next Step: 0; Weighting: 3; Probability: 3/8 (37.5%)
Next Step: 1; Weighting: 3; Probability: 3/8 (37.5%)
Next Step: 2; Weighting: 2; Probability: 2/8 (25.0%)

In order to understand the calculation of the weighting value, you need to add up all of the weights for the current step, then use that to divide the individual values for a weighting factor. In this example, the total weighting values for all cases where the current step is 0 add up to 8. This gives us the denominator for the calculations we made. Therefore, 25% of the time, we will go from no hi-hat sound to an open hi-hat; 37.5% of the time, we will go to a closed hi-hat and the rest of the time there will be no sound at all.

 

Working with zl

 

The zl object is a single object that works in over 20 different modes as set by the object's first argument. The modes perform list processing functions such as sorting, removing unwanted items and joining lists.

Perhaps the best way to see all of the zl operating modes is to look at the zl help file. Unlock the patcher, select a zl object and choose “Open zl help” from the contextual menu or from the application help menu. The help file is broken into six tabs, since there are so many modes – but you will be able to see all of the ways that zl can be used to bend, fold and mutilate Max lists.

 

Working with vexpr

 

When working with lists, there are times when you want to perform mathematical expressions against all of the elements in a list. Using standard Max math objects (+, etc.) would require splitting, processing and reassembling a list – not the most efficient way of dealing with the problem. There is a solution: the vexpr object.

 

Summary

We started this tutorial by learning about probability tables, and their use in seeding a multislider object's content. From there we covered several ways that a multislider object's content (provided as a list) could be processed using the zl and vexprobjects. Since lists are an integral data structure in the Max environment, these objects will become an often-used part of your programming toolkit.

 

See also: